<template>
  <div class="gin-tabs">
    <div class="gin-tabs-nav" ref="navContainerRef">
      <div class="gin-tabs-nav-item" :ref="el => { if (t === selected) selectedItem = el }" @click="handleClickNav(t)" :class="{selected: selected ===t}" v-for="(t,index) in titles" :key="index">{{t}}</div>
      <div class="gin-tabs-nav-indicator" ref="indicatorRef"></div>
    </div>

    <div class="gin-tabs-content">
      <keep-alive>
        <component :is="selectedComponent" :key="selected"  />
      </keep-alive>
    </div>

  </div>
</template>

<script lang='ts'>
import { computed, onMounted, reactive, ref, watchEffect } from 'vue'

import Tab from './Tab.vue'

export default {
  props: {
    selected: {
      type: String
    }
  },
  setup(props, context) {
    const defaults = context.slots.default()
    const titles = reactive<string[]>([])
    const selectedComponent = computed(() => {
      return defaults.find(each => each.props.title === props.selected)
    })
    defaults.forEach(tag => {
      if (tag.type !== Tab) {
      // 检查子组件类型,不正确则停止渲染
        throw new Error('Tabs 的子组件必须是Tab组件')
      }
      titles.push(tag.props.title)
    })
    const selectedItem = ref<HTMLDivElement>(null)
    const indicatorRef = ref<HTMLDivElement>(null)
    const navContainerRef = ref<HTMLDivElement>(null)
    
    onMounted(() => {
      watchEffect(() => {
        const {width, left} = selectedItem.value.getBoundingClientRect()
        // 指示器的left等于当前nav的left-容器的left
        const {left: navContainerLeft} = navContainerRef.value.getBoundingClientRect()
        
        indicatorRef.value.style.left = left -navContainerLeft + 'px'
        indicatorRef.value.style.width = width + 'px'
      })
    })
    
    const handleClickNav = (title) => {
      context.emit('update:selected', title)
    }
    return {
      titles,
      selectedComponent,
      handleClickNav,
      selectedItem,
      indicatorRef,
      navContainerRef
    }
  }
}
</script>


<style lang="scss">
$blue: #40a9ff;
$color: #333;
$border-color: #d9d9d9;
.gin-tabs {
  &-nav {
    display: flex;
    color: $color;
    border-bottom: 1px solid $border-color;
    position: relative;
    &-indicator {
      position: absolute;
      width: 100px;
      height: 3px;
      background: $blue;
      left: 0;
      bottom: -1px;
      transition: all .25s;
    }
    &-item {
      padding: 8px 0;
      margin: 0 16px;
      cursor: pointer;
      &:first-child {
        margin-left: 0;
      }
      &.selected {
        color: $blue;
      }
    }
    
  }
  &-content {
    padding: 8px 0;
  }
}
</style>